package com.yunmai.library.db;

import android.content.Context;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.GenericRawResults;
import com.j256.ormlite.dao.RawRowMapper;
import com.j256.ormlite.stmt.GenericRowMapper;
import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.support.DatabaseResults;
import java.sql.SQLException;
import java.util.List;

/**
 * 默认的数据库操作实现类,默认使用ormlite
 *
 * @author liyi
 * create at 2018/3/26
 **/
public class DBCall<T> implements Call, GenericRowMapper<String[]> {

  DatabaseMethod databaseMethod;
  Object[] args;
  Context mContext;
  SimpleResultParse mSimpleResultParse;

  DBCall(Context context, DatabaseMethod<T, ?> serviceMethod, Object[] args) {
    this.databaseMethod = serviceMethod;
    this.args = args;
    this.mContext = context;
    mSimpleResultParse = new SimpleResultParse(mContext);
  }

  public synchronized Result request() throws SQLException {
    return databaseMethod.toCall(this, args);
  }

  @Override
  public <T> List<T> query(String sql) throws SQLException {
    Dao dao = DBOpenHelper.getInstance(mContext).getDao(databaseMethod.getEntitie());

    GenericRawResults<Object> results = dao.queryRaw(sql, new RawRowMapper() {
      @Override
      public Object mapRow(String[] strings, String[] strings1) throws SQLException {
        return mSimpleResultParse.parseResult(databaseMethod.getEntitie(), strings, strings1);
      }
    });

    return (List<T>) results.getResults();
  }

  @Override
  public <T> boolean insert(T t) {

    if (t == null) throw new NullPointerException("insert null object");

    if (t instanceof List) {
      List lists = (List) t;
      DBFactory.getInstance(mContext).create(lists, databaseMethod.getEntitie(), true);
      return true;
    }

    return DBFactory.getInstance(mContext).create(t, true) > 0;
  }

  @Override
  public <T> boolean update(T t) {
    if (t == null) throw new NullPointerException("insert null object");

    return DBFactory.getInstance(mContext).update(t, true) > 0;
  }

  @Override
  public <T> boolean delete(T t) {

    if (t == null) throw new NullPointerException("insert null object");

    return DBFactory.getInstance(mContext).delete(t, null, true) > 0;
  }

  @Override public <T> int count() throws SQLException {
    Dao dao = DBOpenHelper.getInstance(mContext).getDao(databaseMethod.getEntitie());

    return (int) dao.countOf();
  }

  @Override public String[] mapRow(DatabaseResults results) throws SQLException {
    int columnN = results.getColumnCount();
    String[] result = new String[columnN];
    for (int colC = 0; colC < columnN; colC++) {
      result[colC] = results.getString(colC);
    }
    return result;
  }
}
